home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / MacSource / TextEditor.old.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-14  |  24.2 KB  |  1,051 lines  |  [TEXT/CWIE]

  1. /*==============================================================================
  2. Project:    POV-Ray
  3.  
  4. Version:    3
  5.  
  6. File:    TextEditor.c
  7.  
  8. Description:
  9.     This file contains Macintosh-specific routines for the
  10.     source code text editor.
  11. ------------------------------------------------------------------------------
  12. Author:
  13.     Symantec, mods by Jim Nitchals, more mods & Think 6 updates by Eduard [esp] Schwan
  14. ------------------------------------------------------------------------------
  15.     from Persistence of Vision(tm) Ray Tracer
  16.     Copyright 1996 Persistence of Vision Team
  17. ------------------------------------------------------------------------------
  18.     NOTICE: This source code file is provided so that users may experiment
  19.     with enhancements to POV-Ray and to port the software to platforms other 
  20.     than those supported by the POV-Ray Team.  There are strict rules under
  21.     which you are permitted to use this file.  The rules are in the file
  22.     named POVLEGAL.DOC which should be distributed with this file. If 
  23.     POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  24.     Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  25.     Forum.  The latest version of POV-Ray may be found there as well.
  26.  
  27.     This program is based on the popular DKB raytracer version 2.12.
  28.     DKBTrace was originally written by David K. Buck.
  29.     DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  30. ------------------------------------------------------------------------------
  31. Change History:
  32.     920815    [jln]    version 1.0 Mac released.
  33.     920908    [esp]    version 1.1 alpha Mac
  34.     920912    [esp]    changed window id to 1000 & moved #define here from POVMac.h
  35.     921110    [esp]    Added TextEditor.h file & pulled in defs to there
  36.     921207    [esp]    Added code to handle zoom box
  37.     921211    [esp]    Fixed bug in Open: if open failed, left New & Open items dimmed
  38.     930710    [esp]    fixed "cancelling of save-as dialog" logic
  39.     930817    [esp]    Added FlushVol calls in SaveFile and SaveAs to force disk update
  40.     931001    [esp]    version 2.0 finished (Released on 10/4/93)
  41.     931119    [djh]    2.0.1 conditionally compiles for PPC machines, keyword __powerc
  42.     940416    [PFS]    2.2.1 greatly reworked to clean up PPC support and provide CodeWarrior projects
  43. ==============================================================================*/
  44.  
  45.  
  46. #include "TextEditor.h"
  47.  
  48. /*==== Standard C headers ====*/
  49. #include <stdio.h>
  50.  
  51. /*==== Mac toolbox headers ====*/
  52.  
  53. #include <types.h>        // basic types
  54. #include <desk.h>        // SystemEdit, etc.
  55. #include <errors.h>        // noErr, etc.
  56. #include <files.h>        // FSOpen, etc. 
  57. #include <fonts.h>        // monaco, etc. 
  58. #include <memory.h>        // NewHandle, etc. 
  59. #include <menus.h>        // MenuHandle, etc. 
  60. #include <packages.h>    // SFGetFile, etc. 
  61. #include <scrap.h>        // ZeroScrap, etc. 
  62. #include <toolutils.h>    // watchCursor, etc. 
  63. #include <windows.h>    // SizeWindow, etc. 
  64. #include <processes.h>    // ExitToShell
  65.  
  66.  
  67. /*==== POV Mac Library routines =====*/
  68.  
  69. #include "PovMac.h"            // fmn_open
  70. #include "UtilLib.h"
  71. #include "ImageWindow.h"    // CloseImageWindow(), gImageWindIsValid
  72. #include "FilePrefs.h"
  73.  
  74. /*==== globals (external scope) ====*/
  75.  
  76. WindowPtr            gSrcWind_Window;
  77. TEHandle            gSrcWind_TEH;
  78. Boolean                gSrcWind_dirty;
  79. Boolean                gSrcWind_visible;
  80. Str255                 gSrcWind_FileName;
  81. short                gSrcWind_VRefNum;
  82.  
  83.  
  84. /*==== globals (local scope) ====*/
  85.  
  86. static    WindowRecord        gWindowRecord;
  87. static    int                    gLineCount;
  88. static    Cursor                gEditCursor;
  89. static    ControlActionUPP    vScrollUPP = NULL;
  90. static    ControlHandle         gSrcWind_VScroll;
  91.  
  92.  
  93. static pascal void ScrollProc(ControlHandle theControl, short theCode);
  94.  
  95. // ==============================================
  96. #define SrcWind_WindID     1000
  97. #define ErrorAlert        256
  98. #define    AdviseAlert        257
  99.  
  100. #define fmNew            1
  101. #define fmRevert        7
  102. #define fmPageSetUp        9
  103. #define fmPrint            10
  104. #define fmQuit            13
  105.  
  106. #define aaSave            1
  107. #define aaDiscard        2
  108. #define aaCancel        3
  109.  
  110. #define SBarWidth        15
  111.  
  112. #define    ours(w)        ((gSrcWind_Window != NULL) && (w == gSrcWind_Window))
  113.  
  114. #define    kUntitledFName    "\pUntitled.POV"
  115.  
  116.  
  117. // ==============================================
  118. int SetUpFiles(void)
  119. {
  120.     pStrCopy(kUntitledFName, gSrcWind_FileName);
  121.     gSrcWind_VRefNum = 0;
  122.     gSrcWind_dirty = 0;
  123.     return 0; // should be void fn!?
  124. }
  125.  
  126.  
  127.  
  128. // ==============================================
  129. int DoFile(int item)
  130. {
  131.     short     vRef, refNum;
  132.     Str255    fn;
  133.  
  134.     switch (item) {
  135.  
  136.         case fmn_open:
  137.             HideWindow(gSrcWind_Window);    /* gives a sense of closing the old file. */
  138.             if (OldFile(fn, &vRef))
  139.             {
  140.                 gSrcWind_VRefNum = 0;
  141.                 gSrcWind_dirty = 0;
  142.                 if (FSOpen(fn, vRef, &refNum)==noErr) {
  143.                     if (ReadFile(refNum, gSrcWind_TEH)==noErr) {
  144.                         pStrCopy(fn, gSrcWind_FileName);
  145.                         gSrcWind_VRefNum = vRef;
  146.                         SetWTitle(gSrcWind_Window, gSrcWind_FileName);
  147.                     }
  148.                     if (FSClose(refNum)==noErr) ;
  149.                     ShowWindow(gSrcWind_Window);
  150.                     gSrcWind_visible = TRUE;
  151.                     TESetSelect(0, 0, gSrcWind_TEH);
  152.                     ShowSelect();
  153.                 }
  154.                 else
  155.                     FileError("\pError opening ", fn);
  156.             }
  157.             break;
  158.  
  159.         case fmn_close:
  160.             if (gSrcWind_dirty)
  161.             {
  162.                 int    notClosed=0;
  163.                 ParamText("\pSave changes to ā€œ",
  164.                         gSrcWind_FileName,
  165.                         "\pā€?", "\p");
  166.                 switch (Alert(AdviseAlert, 0L))
  167.                 {
  168.                 case aaSave:
  169.                     if (gSrcWind_VRefNum == 0)
  170.                     { // create new file
  171.                         pStrCopy(gSrcWind_FileName, fn);
  172.                         if (!SaveAs(fn, &vRef))
  173.                             notClosed=1;
  174.                     }
  175.                      else // save existing file
  176.                         if (!SaveFile(gSrcWind_FileName, gSrcWind_VRefNum))
  177.                             notClosed=1;
  178.                      break;
  179.                  case aaCancel:
  180.                     notClosed=1;
  181.                  case aaDiscard:
  182.                     gSrcWind_dirty = 0;
  183.                  }
  184.                 if (notClosed)
  185.                     return 0; // error, just return
  186.              } // if dirty
  187.  
  188.             CloseMyWindow();
  189.             break;
  190.  
  191.         case fmn_save:
  192.             // if file already open
  193.             if (gSrcWind_VRefNum != 0)
  194.             {
  195.                 if (!SaveFile(gSrcWind_FileName, gSrcWind_VRefNum))
  196.                     return(0);
  197.                 break;
  198.             }
  199.             // else drop through to here..
  200.  
  201.         case fmn_saveas:
  202.             pStrCopy(gSrcWind_FileName, fn);
  203.             if (SaveAs(fn, &vRef))
  204.             {
  205.                 pStrCopy(fn, gSrcWind_FileName);
  206.                 gSrcWind_VRefNum = vRef;
  207.                 SetWTitle(gSrcWind_Window, gSrcWind_FileName);
  208.             }
  209.             else
  210.                 return(0);
  211.             break;
  212.  
  213.         case fmRevert:
  214.             ParamText("\pRevert to last saved version of ā€œ",
  215.                     gSrcWind_FileName, "\pā€?", "\p");
  216.             switch (Alert(AdviseAlert, 0L)) {
  217.             case aaSave:
  218.                 HidePen();
  219.                 TESetSelect(0, (**gSrcWind_TEH).teLength, gSrcWind_TEH);
  220.                 ShowPen();
  221.                 TEDelete(gSrcWind_TEH);
  222.                 if ((gSrcWind_VRefNum != 0) &&
  223.                     (FSOpen(gSrcWind_FileName, gSrcWind_VRefNum, &refNum)==noErr))
  224.                 {
  225.                     gSrcWind_dirty = (ReadFile(refNum, gSrcWind_TEH)==noErr); 
  226.                     if (FSClose(refNum)==noErr) ;
  227.                 }
  228.                 ShowWindow(gSrcWind_Window);
  229.                 gSrcWind_visible = TRUE;
  230.                 UpdateWindow(gSrcWind_Window);
  231.              case aaCancel:
  232.              case aaDiscard:
  233.                 return(0);
  234.              }
  235.     
  236.             break;
  237.  
  238. #if defined(_DO_PRINTING_SOMEDAY_)
  239.         case fmPageSetUp:
  240.             DoPageSetUp();
  241.             break;
  242.         case fmPrint:
  243.             PrintText( (**gSrcWind_TEH).hText, (long)(**gSrcWind_TEH).teLength, (GrafPtr)gSrcWind_Window,
  244.                             StringWidth("\pmmmm"));
  245.             break;
  246. #endif // DO_PRINTING_SOMEDAY
  247.         case fmQuit: 
  248.             if (DoFile(fmn_close))
  249.                 ExitToShell();
  250.     }
  251.     return(1);
  252. }
  253.  
  254.  
  255.  
  256. // ==============================================
  257. static Point SFwhere;
  258. static SFReply reply;
  259.  
  260.  
  261. int SaveAs(Str255 fn, short *vRef)
  262. {
  263.     short refNum;
  264.     
  265.     if (NewFile(fn, vRef)) 
  266.         if (!CreateFile(fn, vRef, &refNum))
  267.         {
  268.             FileError("\pError creating file ", fn);
  269.             return (0);
  270.         }
  271.         else
  272.         {
  273.             char hstate;
  274.             
  275.             hstate = HGetState((**gSrcWind_TEH).hText);
  276.             HLock((**gSrcWind_TEH).hText);
  277.             if (WriteFile(refNum, (*(**gSrcWind_TEH).hText), (long)(**gSrcWind_TEH).teLength))
  278.             {
  279.                 FileError("\pError writing file ", fn);
  280.                 return (0);
  281.             }
  282.             HSetState((**gSrcWind_TEH).hText, hstate);
  283.             FSClose(refNum);
  284.             gSrcWind_dirty = 0;
  285.             // flush any buffers to disk
  286.             FlushVol(NULL, *vRef);
  287.             return(1);
  288.         }
  289.     return (0);
  290. }
  291.  
  292.  
  293.  
  294. // ==============================================
  295. int SaveFile(Str255 fn, short vRef)
  296. {
  297.     short refNum;
  298.     short anError;
  299.  
  300.     anError = FSOpen(fn, vRef, &refNum);
  301.     if (anError != noErr)
  302.     {
  303.         FileError("\pError opening file ", fn);
  304.         return (1);
  305.     }
  306.     else
  307.     {
  308.         char hstate;
  309.         
  310.         hstate = HGetState((**gSrcWind_TEH).hText);
  311.         HLock((**gSrcWind_TEH).hText);
  312.         anError = WriteFile(refNum, (*(**gSrcWind_TEH).hText), (long)(**gSrcWind_TEH).teLength);
  313.         if (anError)
  314.             FileError("\pError writing file ", fn);
  315.         HSetState((**gSrcWind_TEH).hText, hstate);
  316.         gSrcWind_dirty = 0;
  317.         FSClose(refNum);
  318.         // save prefs out too
  319.         FilePrefs_Write(vRef, fn);                            
  320.         // flush any buffers to disk
  321.         FlushVol(NULL, vRef);
  322.         return(1);
  323.     }
  324. }
  325.  
  326.  
  327.  
  328. // ==============================================
  329. int NewFile(Str255 fn, short *vRef)
  330. {
  331.     GetBestDialogPos(&SFwhere, (WindowPtr)&gp2wWindow);
  332.     SFPutFile(SFwhere, "\pSave POV-Ray text file as", fn, 0L, &reply);
  333.     if (!reply.good)
  334.         return (0);
  335.     else {
  336.         pStrCopy(reply.fName, fn);
  337.         *vRef = reply.vRefNum;
  338.         return(1);
  339.     }
  340. }
  341.  
  342.  
  343.  
  344. // ==============================================
  345. int OldFile(Str255 fn, short *vRef)
  346. {
  347.     SFTypeList    myTypes;
  348.     
  349.     myTypes[0]='TEXT';
  350.  
  351.     GetBestDialogPos(&SFwhere, (WindowPtr)&gp2wWindow);
  352.     SFGetFile(SFwhere, "\p", 0L, 1, myTypes, 0L, &reply );
  353.  
  354.     if (!reply.good)
  355.         return (0);
  356.     else {
  357.         pStrCopy(reply.fName, fn);
  358.         *vRef = reply.vRefNum;
  359.         return(1);
  360.     }
  361. }
  362.  
  363.  
  364.  
  365. // ==============================================
  366. int CreateFile(Str255 fn, short *vRef, short *theRef)
  367. {
  368.     OSErr io;
  369.     
  370.     io=Create(fn, *vRef, kAppSignature, 'TEXT');
  371.     if ((io == noErr) || (io == dupFNErr))
  372.         io = FSOpen(fn, *vRef, theRef );
  373.  
  374.     return ((io == noErr) || (io == dupFNErr));
  375. }
  376.  
  377.  
  378.  
  379. // ==============================================
  380. int WriteFile(short refNum, char *p, long num)
  381. {
  382.     OSErr io;            
  383.     /* gee,    somebody should check the return code for errors */
  384.     io=FSWrite(refNum, &num, p);
  385.     if (io)
  386.         return(io);
  387.     io=SetEOF(refNum, num);
  388.     return(io);
  389. }
  390.  
  391.  
  392.  
  393. // ==============================================
  394. #define READ_BUF_SIZE    1024L
  395. int ReadFile(short refNum, TEHandle textH)
  396. {
  397.     OSErr    io = noErr;
  398.     long    totalBytes, count;
  399.     Ptr        buffer;
  400.  
  401.     // allocate temp buffer to read into
  402.     buffer = NewPtr(READ_BUF_SIZE);
  403.     if (buffer == NULL)
  404.         return -108; // out of mem
  405.  
  406.     // get rid of any previous TE stuff
  407.     (**textH).selStart = 0;
  408.     (**textH).selEnd = (**textH).teLength;
  409.     TEDelete(textH);
  410.     // how many total bytes in file?
  411.     GetEOF(refNum, &totalBytes);
  412.     if (totalBytes > 32767L)
  413.         return (999);
  414.     // read the file, "READ_BUF_SIZE" bytes at a time
  415.     do {
  416.         // how much to read this pass?
  417.         count = (totalBytes >= READ_BUF_SIZE) ? READ_BUF_SIZE : totalBytes;
  418.         // read it
  419.         if (count > 0L)
  420.             io = FSRead(refNum, &count, buffer);
  421.         // stick chars into TE buffer
  422.         if (count > 0L)
  423.             TEInsert(buffer, count, textH);
  424.         // calculate how much is left to read
  425.         totalBytes -= count;
  426.     } while ((io==noErr) && (totalBytes > 0L));
  427.     // done with temp buffer
  428.     DisposePtr(buffer);
  429.  
  430.     return (io);
  431. }
  432.  
  433.  
  434.  
  435. // ==============================================
  436. /* copies a pascal string from p1 to p2 */
  437. int pStrCopy(StringPtr p1, StringPtr p2)
  438. {
  439.     register int len = *p1;    // added asignment
  440.     
  441.     *(p2++) = *(p1++);            // added parens
  442.     while (--len>=0) *(p2++)=*(p1++);    // added parens
  443.     return 0; // should be void fn!?
  444. }
  445.  
  446.  
  447.  
  448. // ==============================================
  449. int FileError(Str255 s, Str255 f)
  450. {
  451.     ParamText(s, f,"\p", "\p");
  452.     Alert(ErrorAlert, 0L);
  453.     return 0; // should be void fn!?
  454. }
  455.  
  456.  
  457.  
  458. // ==============================================
  459. void PreInitWindows(void)
  460. {
  461.     if (gSrcWind_Window == 0)
  462.     {
  463.         SetUpWindows();
  464.         HideWindow(gSrcWind_Window);    /* just in case it's already visible */
  465.     }
  466. }
  467.  
  468.  
  469.  
  470. // ==============================================
  471. int SetUpWindows(void)
  472. {
  473.     Rect    viewRect;
  474.     Rect    vScrollRect;
  475.  
  476.     gSrcWind_Window = GetNewWindow(SrcWind_WindID, &gWindowRecord, (WindowPtr)NULL);
  477.     if (!gSrcWind_Window)
  478.         return 1;
  479.     SetPort(gSrcWind_Window);
  480.     TextFont(monaco);
  481.     TextSize(9);
  482.     vScrollRect = (*gSrcWind_Window).portRect;
  483.     vScrollRect.left = vScrollRect.right-SBarWidth;
  484.     vScrollRect.right += 1;
  485.     vScrollRect.bottom -= SBarWidth-1;
  486.     vScrollRect.top -= 1;
  487.     gSrcWind_VScroll = NewControl( gSrcWind_Window, &vScrollRect, "\pSrcVScroll", 1, 0, 0, 0,
  488.         scrollBarProc, 0L);
  489.  
  490.     viewRect = qd.thePort->portRect;
  491.     viewRect.right -= SBarWidth;
  492.     viewRect.bottom -= SBarWidth;
  493.     InsetRect(&viewRect, 4, 4);
  494.     gSrcWind_TEH = TENew(&viewRect, &viewRect);
  495.     if (gSrcWind_TEH)
  496.     {
  497.         // turn on auto-scrolling and outline hilighting
  498.         TEDeactivate(gSrcWind_TEH);
  499. /*
  500. turn on autoscrolling if/when we add a clickloop proc...
  501.         (void)TEFeatureFlag(teFAutoScr,       teBitSet, gSrcWind_TEH);
  502. */
  503.         (void)TEFeatureFlag(teFOutlineHilite, teBitSet, gSrcWind_TEH);
  504.     }
  505.     SetView((WindowPtr) qd.thePort);
  506.  
  507.     if (gSrcWind_VScroll)
  508.         HideControl(gSrcWind_VScroll);
  509.  
  510.     gSrcWind_dirty = 0;
  511.     return 0; // should be void fn!?
  512. }
  513.  
  514.  
  515.  
  516. // ==============================================
  517. int AdjustText(void)
  518. {
  519.     int        oldScroll, newScroll, delta;
  520.     
  521.     oldScroll = (**gSrcWind_TEH).viewRect.top - (**gSrcWind_TEH).destRect.top;
  522.     newScroll = GetControlValue(gSrcWind_VScroll) * (**gSrcWind_TEH).lineHeight;
  523.     delta = oldScroll - newScroll;
  524.     if (delta != 0)
  525.       TEScroll(0, delta, gSrcWind_TEH);
  526.     SetVScroll();
  527.     return 0; // should be void fn!?
  528. }
  529.  
  530.  
  531.  
  532. // ==============================================
  533. int SetVScroll(void)
  534. {
  535.     register int    n;
  536.     
  537.     n = (**gSrcWind_TEH).nLines-gLineCount;
  538.  
  539.     if ((**gSrcWind_TEH).teLength > 0 && (*((**gSrcWind_TEH).hText))[(**gSrcWind_TEH).teLength-1]=='\r')
  540.         n++;
  541.  
  542.     SetControlMaximum(gSrcWind_VScroll, n > 0 ? n : 0);
  543.     ShowControl(gSrcWind_VScroll);
  544.     return 0; // should be void fn!?
  545. }
  546.  
  547.  
  548.  
  549. // ==============================================
  550. int ShowSelect(void)
  551. {
  552.     register    int        topLine, bottomLine, theLine;
  553.     
  554.     SetVScroll();
  555.     AdjustText();
  556.     
  557.     topLine = GetControlValue(gSrcWind_VScroll);
  558.     bottomLine = topLine + gLineCount;
  559.     
  560.     // count up the lines to current
  561.     if ((**gSrcWind_TEH).selStart < (**gSrcWind_TEH).lineStarts[topLine] ||
  562.             (**gSrcWind_TEH).selStart >= (**gSrcWind_TEH).lineStarts[bottomLine]) {
  563.         for (    theLine = 0;
  564.                 (**gSrcWind_TEH).selStart >= (**gSrcWind_TEH).lineStarts[theLine];
  565.                 theLine++)
  566.             ;
  567.         SetControlValue(gSrcWind_VScroll, theLine - gLineCount / 2);
  568.         AdjustText();
  569.     }
  570.     return 0; // should be void fn!?
  571. }
  572.  
  573.  
  574.  
  575. // ==============================================
  576. void SelectAllText(void)
  577. {    
  578.     TESetSelect(0, -1, gSrcWind_TEH);
  579.     SetVScroll();
  580.     AdjustText();    
  581. }
  582.  
  583.  
  584.  
  585. // ==============================================
  586. int SetView(WindowPtr w)
  587. {
  588.     (**gSrcWind_TEH).viewRect = w->portRect;
  589.     (**gSrcWind_TEH).viewRect.right -= SBarWidth;
  590.     (**gSrcWind_TEH).viewRect.bottom -= SBarWidth;
  591.     InsetRect(&(**gSrcWind_TEH).viewRect, 4, 4);
  592.  
  593.     gLineCount = ((**gSrcWind_TEH).viewRect.bottom-(**gSrcWind_TEH).viewRect.top)/(**gSrcWind_TEH).lineHeight;
  594.     (**gSrcWind_TEH).viewRect.bottom = (**gSrcWind_TEH).viewRect.top + (**gSrcWind_TEH).lineHeight*gLineCount;
  595.     (**gSrcWind_TEH).destRect.right = (**gSrcWind_TEH).viewRect.right;
  596.     TECalText(gSrcWind_TEH);
  597.     return 0; // should be void fn!?
  598. }
  599.  
  600.  
  601.  
  602. // ==============================================
  603. int UpdateWindow(WindowPtr theWindow)
  604. {
  605.     GrafPtr    savePort;
  606.     
  607.     GetPort(&savePort);
  608.     SetPort(theWindow);
  609.  
  610.     BeginUpdate(theWindow);
  611.     EraseRect(&theWindow->portRect);
  612.     DrawControls(theWindow);
  613.     DrawGrowIcon(theWindow);
  614.     TEUpdate(&theWindow->portRect, gSrcWind_TEH);
  615.     EndUpdate(theWindow);
  616.  
  617.     SetPort(savePort);
  618.     return 0; // should be void fn!?
  619. }
  620.  
  621.  
  622. // ==============================================
  623. // So outside can call scrolling without accessing locals
  624. void ScrollEditHome(void)
  625. {
  626.     SetControlValue(gSrcWind_VScroll, 0);
  627.     AdjustText();
  628. }
  629.  
  630. // ==============================================
  631. // So outside can call scrolling without accessing locals
  632. void ScrollEditEnd(void)
  633. {
  634.     SetControlValue(gSrcWind_VScroll, (**gSrcWind_TEH).teLength);
  635.     AdjustText();
  636. }
  637.  
  638. // ==============================================
  639. // So outside can call scrolling without accessing locals
  640. void ScrollEditPage(short thePartCode)
  641. {
  642.     ScrollProc(gSrcWind_VScroll, thePartCode);
  643. }
  644.  
  645.  
  646. // ==============================================
  647. static pascal void ScrollProc(ControlHandle theControl, short theCode)
  648. {
  649.     int    pageSize;
  650.     int    scrollAmt;
  651.     int oldCtl;
  652.     
  653.     if (theCode == 0)
  654.         return ;
  655.     
  656.     pageSize = ((**gSrcWind_TEH).viewRect.bottom-(**gSrcWind_TEH).viewRect.top) / 
  657.             (**gSrcWind_TEH).lineHeight - 1;
  658.             
  659.     switch (theCode) {
  660.         case kControlUpButtonPart: 
  661.             scrollAmt = -1;
  662.             break;
  663.         case kControlDownButtonPart: 
  664.             scrollAmt = 1;
  665.             break;
  666.         case kControlPageUpPart: 
  667.             scrollAmt = -pageSize;
  668.             break;
  669.         case kControlPageDownPart: 
  670.             scrollAmt = pageSize;
  671.             break;
  672.     }
  673.  
  674.     oldCtl = GetControlValue(theControl);
  675.     SetControlValue(theControl, oldCtl+scrollAmt);
  676.  
  677.     AdjustText();
  678. }
  679.  
  680.  
  681.  
  682. // ==============================================
  683. int DoContent(WindowPtr theWindow, EventRecord *theEvent)
  684. {
  685.     short            cntlCode;
  686.     ControlHandle     theControl;
  687.     GrafPtr            savePort;
  688.     
  689.     GetPort(&savePort);
  690.     SetPort(theWindow);
  691.  
  692.     GlobalToLocal(&theEvent->where);
  693.     if ((cntlCode = FindControl(theEvent->where, theWindow, &theControl)) == 0) {
  694.         if (PtInRect(theEvent->where, &(**gSrcWind_TEH).viewRect))
  695.             TEClick(theEvent->where, (theEvent->modifiers & shiftKey)!=0, gSrcWind_TEH);
  696.     } else if (cntlCode == kControlIndicatorPart) {
  697.         TrackControl(theControl, theEvent->where, 0L);
  698.         AdjustText();
  699.     } else
  700.         TrackControl(theControl, theEvent->where, vScrollUPP);
  701.  
  702.     SetPort(savePort);
  703.     return 0; // should be void fn!?
  704. }
  705.  
  706.  
  707.  
  708. // ==============================================
  709. void MyResizeWindow(WindowPtr w, short h, short v)
  710. {
  711.     Rect    oldHorizBar;
  712.     Rect     r;
  713.     
  714.     SetPort(w);
  715.  
  716.     oldHorizBar = w->portRect;
  717.     oldHorizBar.top = oldHorizBar.bottom - (SBarWidth+1);
  718.  
  719.     SizeWindow(w, h, v, false);
  720.  
  721.     // remember this new size in prefs
  722.     GetGlobalWindowRect(w, &(**gFilePrefs_h).srcWind_pos);
  723.  
  724.     InvalRect(&w->portRect);
  725.     
  726.     SetView(w);
  727.  
  728.     EraseRect(&oldHorizBar);
  729.     
  730.     MoveControl(gSrcWind_VScroll, w->portRect.right - SBarWidth, w->portRect.top-1);
  731.     SizeControl(gSrcWind_VScroll, SBarWidth+1, w->portRect.bottom - w->portRect.top-(SBarWidth-2));
  732.     r = (**gSrcWind_VScroll).contrlRect;
  733.     ValidRect(&r);
  734.  
  735.     SetVScroll();
  736.     AdjustText();
  737.     
  738. } // MyResizeWindow
  739.  
  740.  
  741.  
  742. // ==============================================
  743. static void MyGrowWindow(WindowPtr w, Point p)
  744. {
  745.     GrafPtr        savePort;
  746.     long        theResult;
  747.     Rect        r;
  748.     
  749.     GetPort(&savePort);
  750.     SetPort(w);
  751.  
  752.     GetMaxGrowRect(w, &r);    
  753.     theResult = GrowWindow(w, p, &r);
  754.     if (theResult != 0)
  755.         MyResizeWindow(w, LoWord(theResult), HiWord(theResult));
  756.  
  757.     SetPort(savePort);
  758. } // MyGrowWindow
  759.  
  760.  
  761.  
  762. // ==============================================
  763. int CloseMyWindow(void)
  764. {
  765.  
  766.     if (gSrcWind_VRefNum != 0)
  767.     {
  768.         FilePrefs_Write(gSrcWind_VRefNum, gSrcWind_FileName);    // Save window info
  769.         // OK, now we're done with this file, release the pesky Working Directory
  770. //        CloseWD(gSrcWind_VRefNum);
  771.     }
  772.  
  773.     // if there's a window (always) then hide it
  774.     if (gSrcWind_Window)
  775.         HideWindow(gSrcWind_Window);
  776.     gSrcWind_visible = false;
  777.  
  778.     // Image window also no longer valid!
  779.     CloseImageWindow();
  780.     gImageWindIsValid = false;
  781.  
  782.     // get rid of TE text (select all & delete)
  783.     if (gSrcWind_TEH)
  784.     {
  785.         TESetSelect(0, (**gSrcWind_TEH).teLength, gSrcWind_TEH);
  786.         TEDelete(gSrcWind_TEH);
  787.     }
  788.  
  789.     SetVScroll();
  790.  
  791.     SetUpFiles();
  792.  
  793.     return 0; // should be void fn!?
  794. }
  795.  
  796.  
  797. // ==============================================
  798. int    DoActivateEditor(Boolean becomingActive)
  799. {
  800.     if (becomingActive)
  801.     {
  802.         TEActivate(gSrcWind_TEH);
  803.         ShowControl(gSrcWind_VScroll);
  804.         DrawGrowIcon(gSrcWind_Window);
  805.     }
  806.     else
  807.     {
  808.         TEDeactivate(gSrcWind_TEH);
  809.         HideControl(gSrcWind_VScroll);
  810.         /* the growbox should be changed immediately here */
  811.         DrawGrowIcon(gSrcWind_Window);
  812.     }
  813.     return 0; // should be void fn!?
  814. }
  815.  
  816. // ==============================================
  817. int main_init() 
  818. {
  819.     CursHandle    hCurs;
  820.     
  821.     vScrollUPP = NewControlActionProc(ScrollProc);
  822.     // Note: iBeamCursor & watchCursor are defined in ToolUtils.h
  823.     hCurs = GetCursor(iBeamCursor);
  824.     gEditCursor = **hCurs;
  825.     gSrcWind_Window = NULL;
  826.     SetUpFiles();
  827.     PreInitWindows();
  828.     return 0;
  829. }
  830.  
  831.  
  832. // ==============================================
  833. int DoEditMouseDown(int windowPart, WindowPtr whichWindow, EventRecord *myEvent)
  834. {
  835.     switch (windowPart) {
  836.         case inGoAway:
  837.             if (ours(whichWindow) && (gDoingRender == 0))
  838.                 if (TrackGoAway(gSrcWind_Window, myEvent->where))
  839.                     DoFile(fmn_close);
  840.             break;
  841.  
  842.         case inDrag:
  843.             if (ours(whichWindow))
  844.             {
  845.                 SelectWindow(whichWindow);
  846.                 DragWindow(whichWindow, myEvent->where, &gDragBounds);
  847.                 GetGlobalWindowRect(whichWindow, &(**gFilePrefs_h).srcWind_pos);
  848.             }
  849.             break;
  850.  
  851.         case inGrow:
  852.             if (ours(whichWindow))
  853.                 MyGrowWindow(whichWindow, myEvent->where);
  854.             break;
  855.  
  856.         case inZoomIn:
  857.         case inZoomOut:
  858.             SelectWindow(whichWindow);
  859.             if (TrackBox(whichWindow, myEvent->where, windowPart))
  860.             {
  861.                 EraseRect(&((WindowPtr)whichWindow)->portRect);
  862.                 ZoomWindow((WindowPtr)whichWindow, windowPart, (WindowPtr)whichWindow==FrontWindow());
  863.                 MyResizeWindow(whichWindow,
  864.                         whichWindow->portRect.right - whichWindow->portRect.left,
  865.                         whichWindow->portRect.bottom - whichWindow->portRect.top);
  866.             }
  867.             break;
  868.  
  869.         case inContent:
  870.             if (whichWindow != FrontWindow())
  871.                 SelectWindow(whichWindow);
  872.             else if (ours(whichWindow))
  873.                 DoContent(whichWindow, myEvent);
  874.             break;
  875.     }
  876.     return 0; // should be void fn!?
  877. }
  878.  
  879.  
  880.  
  881. // ==============================================
  882. int MaintainCursor(void)
  883. {
  884.     Point        pt;
  885.     WindowPeek    wPtr;
  886.     GrafPtr        savePort;
  887.     
  888.     if (ours((WindowPtr)(wPtr=(WindowPeek)FrontWindow()))) {
  889.         GetPort(&savePort);
  890.         SetPort((GrafPtr)wPtr);
  891.         GetMouse(&pt);
  892.         if (PtInRect(pt, &(**gSrcWind_TEH).viewRect ) )
  893.             SetCursor( &gEditCursor);
  894.         else
  895.             SetCursor(&qd.arrow);
  896.         SetPort(savePort);
  897.     }
  898.     return 0; // should be void fn!?
  899. }
  900.  
  901.  
  902. // ==============================================
  903. #if defined(_DO_PRINTING_SOMEDAY_)
  904.  
  905. #define topMargin 20
  906. #define leftMargin 20
  907. #define bottomMargin 20
  908. #define tabChar    ((char)'\t')
  909.  
  910.  
  911. static    THPrint    hPrint = NULL;
  912. static    int        tabWidth;
  913.  
  914.  
  915.     /**
  916.      **        Prototypes for private functions.
  917.      **        (They really should be static.)
  918.      **
  919.      **/
  920.  
  921. int    CheckPrintHandle(void);
  922. int MyDrawText(char *p, int count);
  923. int PrDoc(char **hText, long count, THPrint hPrint, int font, int size);
  924. int HowMany(void);
  925.  
  926.  
  927. // ==============================================
  928. PleaseWait()
  929. {
  930.     ShowWatchCursor();
  931. }
  932.  
  933.  
  934. // ==============================================
  935. CheckPrintHandle()
  936. {
  937.     if (hPrint==NULL) 
  938.         PrintDefault(hPrint = (TPrint **) NewHandle(sizeof( TPrint)));
  939. }
  940.  
  941.  
  942. // ==============================================
  943. DoPageSetUp()
  944. {
  945.     PrOpen();
  946.     CheckPrintHandle();
  947.     if (PrStlDialog(hPrint)) ;
  948.     PrClose();
  949. }
  950.  
  951.  
  952. // ==============================================
  953. MyDrawText(char    *p, int count)
  954. {
  955.     register char    *p1, *p2;
  956.     int                len;
  957.     Point            pt;
  958.  
  959.     p1 = p;
  960.     p2 = p+count;
  961.     while (p<p2) {
  962.         while ((p1<p2) && (*p1 !=tabChar)) *p1++;
  963.         if ((len=p1-p)>0) DrawText(p, 0, p1-p);
  964.         if (*p1==tabChar) {
  965.             GetPen(&pt);
  966.             Move((tabWidth-(pt.h-leftMargin)%tabWidth), 0);
  967.             *p1++;
  968.         }
  969.         p = p1;
  970.     }
  971. }
  972.  
  973.  
  974. // ==============================================
  975. PrDoc(char **hText, long count, THPrint hPrint, int font, int size)
  976. {
  977.     register int     line = 0;
  978.     register int     lastLineOnPage = 0;
  979.     int                length;
  980.     Rect             printRect;
  981.     int             linesPerPage;
  982.     int             lineBase;
  983.     int             lineHeight;
  984.     register char     *ptr, *p1;
  985.     FontInfo        info;
  986.     TPPrPort        printPort;
  987.  
  988.     printPort = PrOpenDoc(hPrint, 0L, 0L);
  989.     SetPort((GrafPtr)printPort);
  990.     TextFont(font);
  991.     TextSize(size);
  992.     printRect = (**hPrint).prInfo.rPage;
  993.     GetFontInfo(&info);
  994.     lineHeight = info.leading+info.ascent+info.descent;
  995.     linesPerPage = 
  996.         (printRect.bottom-printRect.top-topMargin-bottomMargin)/lineHeight;
  997.     HLock(hText);
  998.     ptr = p1 = (*hText);
  999.     do {
  1000.         PrOpenPage(printPort, 0L);
  1001.         lastLineOnPage += linesPerPage;
  1002.         MoveTo( printRect.left+leftMargin, 
  1003.             (lineBase = printRect.top+lineHeight) );
  1004.         do {
  1005.             /* PrintLine: */
  1006.             while ((ptr<=(*hText)+count) && (*ptr++ != (char)'\r')) ;
  1007.             if ((length=(int)(ptr-p1)-1)>0)
  1008.                 MyDrawText(p1, length);
  1009.             MoveTo( printRect.left+leftMargin, (lineBase += lineHeight));
  1010.             p1 = ptr;
  1011.         } while ((++line != lastLineOnPage) && (ptr<(*hText)+count));
  1012.         PrClosePage(printPort);
  1013.     } while (ptr<(*hText)+count);
  1014.     HUnlock(hText);
  1015.     PrCloseDoc(printPort);
  1016. }
  1017.  
  1018.  
  1019. // ==============================================
  1020. PrintText(char    **hText, long length, GrafPtr gp, int tabPixels)
  1021. {
  1022.     GrafPtr        savePort;
  1023.     TPrStatus    prStatus;
  1024.     int            copies;
  1025.     
  1026.     PrOpen();
  1027.     CheckPrintHandle();
  1028.     tabWidth = tabPixels;
  1029.     SetCursor(&qd.arrow);
  1030.     if (PrJobDialog(hPrint) != 0) {
  1031.         PleaseWait();
  1032.         GetPort(&savePort);
  1033.         for (copies=HowMany(); copies>0; copies--) {
  1034.             PrDoc (hText, length, hPrint, (*gp).txFont, (*gp).txSize);
  1035.             PrPicFile(hPrint, 0L, 0L, 0L, &prStatus);
  1036.         }
  1037.         SetPort(savePort);
  1038.     }
  1039.     PrClose();
  1040. }
  1041.  
  1042.  
  1043. // ==============================================
  1044. int HowMany(void)
  1045. {
  1046.     return( ((**hPrint).prJob.bJDocLoop==bDraftLoop) ? 
  1047.                 (**hPrint).prJob.iCopies : 1 );
  1048. }
  1049.  
  1050. #endif // DO_PRINTING_SOMEDAY
  1051.